package cn.jobstart.common.excel;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.style.AbstractCellStyleStrategy;
import cn.jobstart.common.SkList;
import cn.jobstart.common.StringUtil;
import org.apache.poi.ss.usermodel.Workbook;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 导出excel
 *
 * @author sunke
 * @version 1.0
 * @date 2021-07-13 14:43
 */
public class EasyExcelUtil {


    /**
     * 导出数据
     *
     * @param fileName
     * @param outputStream
     * @param dataList
     * @param head
     * @throws Exception
     */
    public static void excelData(String fileName, OutputStream outputStream, List dataList, Class head) throws Exception {

        if (StringUtil.isNullOrEmpty(dataList)) {
            dataList = new ArrayList();
        }

        EasyExcel.write(outputStream, head)
                .inMemory(true) // 注意，此项配置不能少
                .sheet(fileName)
                .registerWriteHandler(SkHorizontalCellStyleStrategy.defaultStyle())
                .registerWriteHandler(new CustomCellWriteHandler())
                .doWrite(dataList);

    }

    public static void excelData(String fileName, OutputStream outputStream, List dataList, Class head, AbstractCellStyleStrategy handler) throws Exception {

        if (StringUtil.isNullOrEmpty(dataList)) {
            dataList = new ArrayList();
        }

        EasyExcel.write(outputStream, head)
                .inMemory(true) // 注意，此项配置不能少
                .sheet(fileName)
                .registerWriteHandler(SkHorizontalCellStyleStrategy.defaultStyle())
                .registerWriteHandler(new CustomCellWriteHandler())
                .registerWriteHandler(handler)
                .doWrite(dataList);

    }


    /**
     * 多sheet
     *
     * @param outputStream
     * @param mapDataList  key sheet 名称  value sheet 的数据
     * @param head
     * @throws Exception
     */
    public static <T> void excelData(OutputStream outputStream, Map<String, List<T>> mapDataList, Class head) throws Exception {

        if (StringUtil.isNullOrEmpty(mapDataList)) {

            return;
        }

        ExcelWriter excelWriter = EasyExcel.write(outputStream, head)
                .inMemory(true)

                .registerWriteHandler(SkHorizontalCellStyleStrategy.defaultStyle())
                .registerWriteHandler(new CustomCellWriteHandler())
                .build();


        AtomicInteger i = new AtomicInteger();
        // 去调用写入,这里我调用了五次，实际使用时根据数据库分页的总的页数来。这里最终会写到5个sheet里面
        mapDataList.forEach((sheetName, dataList) -> {

            WriteSheet writeSheet = EasyExcel.writerSheet(i.getAndIncrement(), sheetName).build();
            excelWriter.write(dataList, writeSheet);

        });


        // 千万别忘记finish 会帮忙关闭流
        excelWriter.finish();


    }


    public static <T> void excelByCustomHead2(String sheetName, List<T> dataList, List<ExcelExportEntity> headList, ExportParams exportParams, OutputStream outputStream) {
        try {
            if (StringUtil.isNullOrEmpty(dataList) || StringUtil.isNullOrEmpty(headList) || StringUtil.isNullOrEmpty(outputStream)) {
                return;
            }

            if (exportParams == null) {
                exportParams = new ExportParams();
                exportParams.setSheetName(sheetName);
                exportParams.setDataHandler(new ExcelDataHandler());
            }

            //生成excel文档
            Workbook workbook = ExcelExportUtil.exportExcel(exportParams, headList, dataList);

            workbook.write(outputStream);
            workbook.close();
        } catch (IOException e) {

        }

    }

    public static <T> void excelByCustomHead(String sheetName, List<List<T>> dataList, List<String> headList, OutputStream outputStream) {


        List<List<String>> head = SkList.getInstance();

        for (String headStr : headList) {
            List<String> oneHead = SkList.getInstance();
            oneHead.add(headStr);
            head.add(oneHead);
        }


        EasyExcel.write(outputStream)
                // 这里放入动态头
                .head(head).sheet(sheetName)
                // 当然这里数据也可以用 List<List<String>> 去传入
                .doWrite(dataList);


    }

    public static void main(String[] args) {


        try {
            OutputStream outputStream = new FileOutputStream(new File("/Users/sunke/Desktop/aa/1.xlsx"));

            Map<String, List> dataMap = new HashMap<>();

            dataMap.put("产品1", SkList.getInstance().addObjToList("A").addObjToList("B"));
            dataMap.put("产品2", SkList.getInstance().addObjToList("C").addObjToList("D"));


        } catch (Exception e) {
            e.printStackTrace();
        }


    }


    public static void excelResponseData(String fileName, HttpServletResponse response, List dataList, Class head) throws Exception {


        String excelFileName = new String(fileName.getBytes(StandardCharsets.UTF_8), "ISO8859-1");


        //URLEncoder.encode(fileName + ".xlsx", "UTF-8");
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setHeader("Content-disposition", "attachment; filename=" + excelFileName + ".xlsx");
        excelData(fileName, response.getOutputStream(), dataList, head);


    }

    public static void excelResponseData(String fileName, HttpServletResponse response, List dataList, Class head, AbstractCellStyleStrategy handler) throws Exception {

        String excelFileName = new String(fileName.getBytes(StandardCharsets.UTF_8), "ISO8859-1");

        // URLEncoder.encode(fileName + ".xlsx", "UTF-8");
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setHeader("Content-disposition", "attachment; filename=" + excelFileName + ".xlsx");
        excelData(fileName, response.getOutputStream(), dataList, head, handler);


    }



/*
    private List<List<String>> head() {
        List<List<String>> list = new ArrayList<List<String>>();
        List<String> head0 = new ArrayList<String>();
        head0.add("字符串" + System.currentTimeMillis());
        List<String> head1 = new ArrayList<String>();
        head1.add("数字" + System.currentTimeMillis());
        List<String> head2 = new ArrayList<String>();
        head2.add("日期" + System.currentTimeMillis());
        list.add(head0);
        list.add(head1);
        list.add(head2);
        return list;
    }

    private List<List<Object>> dataList() {
        List<List<Object>> list = new ArrayList<List<Object>>();
        for (int i = 0; i < 10; i++) {
            List<Object> data = new ArrayList<Object>();
            data.add("字符串" + i);
            data.add(new Date());
            data.add(0.56);
            list.add(data);
        }
        return list;
    }*/

    /**
     * 自定定义关
     *
     * @param fileName
     * @param response
     * @param dataList
     * @param head
     * @throws Exception
     */
    public static void excelResponseDataNoModel(String fileName, HttpServletResponse response, List<List<Object>> dataList, List<List<String>> head) throws Exception {

        URLEncoder.encode(fileName + ".xlsx", "UTF-8");
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setHeader("Content-disposition", "attachment; filename=" + fileName);

        EasyExcel.write(response.getOutputStream()).head(head).sheet(fileName)
                .registerWriteHandler(SkHorizontalCellStyleStrategy.defaultStyle())
                .registerWriteHandler(new CustomCellWriteHandler())

                .doWrite(dataList);

    }


    public static void excelOutputStreamDataNoModel(String fileName, OutputStream outputStream, List<List<Object>> dataList, List<List<String>> head) throws Exception {


        EasyExcel.write(outputStream).head(head).sheet(fileName)
                .registerWriteHandler(SkHorizontalCellStyleStrategy.defaultStyle())
                .registerWriteHandler(new CustomCellWriteHandler())

                .doWrite(dataList);

    }


}
